#include <stdio.h>
#include <stdlib.h>

// 设计一个顺序表
struct seq_list
{
    int size;  // 记录顺序表里面元素的个数
    int last;  // 尾元素的下标
    int *data; // 顺序表首元素的地址(最重要的一个变量)
};

/*
    设计的各种API的接口
*/
// 初始化的函数
struct seq_list *init_list(int size)
{
    // 给顺序表申请堆空间
    struct seq_list *s = malloc(sizeof(struct seq_list));
    if (s == NULL)
    {
        printf("malloc seq_list fail\n");
        return NULL;
    }

    // 给结构体指针赋值
    s->size = size;                       // 顺序表的大小自定义
    s->last = -1;                         // 刚开始空表的时候 下标值是从-1开始的不是0
    s->data = malloc(sizeof(int) * size); // 存储数据的堆空间
    if (s->data == NULL)
    {
        printf("malloc s->data fail\n");
        return NULL;
    }

    return s;
}

// 尾插
void inset_tail(struct seq_list *s, int num)
{
    // 空表
    //  if(s->last == -1)
    //  {
    //      s->data[0] = num;
    //      s->last++;
    //      return;
    //  }

    // 如果顺序表里面的数据满了 不能再插入了
    if (s->size == s->last + 1)
        return;

    // 非空表(存数据)(这个代码里面已经包含了空表的情况)
    s->data[s->last + 1] = num;
    s->last++; // 数组里面尾元素的下标值+1
}

// 头插
void inset_head(struct seq_list *s, int num)
{
    // 如果是满表
    if (s->size == s->last + 1)
        return;

    // 如果是非空表
    // 先将数组里面的值一个一个往右边挪动一个位置
    int i = 0;
    for (i = s->last; i >= 0; i--)
        s->data[i + 1] = s->data[i];

    s->data[0] = num;
    
    //每插入一个数据下标最大值+1
    s->last++;
}

//尾删
void delete_tail(struct seq_list *s)
{
    //如果是空表
    if(s->last== -1)
        return;

    //非空表
    s->data[s->last] = 0;
    s->last--;
}

//头删
void delete_head(struct seq_list *s)
{
    //如果是空表
    if(s->last== -1)
        return;

    //先将数组里面的值一个一个往左边挪动一个位置    
    int i = 0;
    for(i = 1;i<=s->last;i++)
        s->data[i-1] = s->data[i];
    
    //清空最后一个元素的值
    s->data[s->last] = 0;
    s->last--;
}

// 遍历顺序表
void display(struct seq_list *s)
{
    int i = 0;
    for (i = 0; i < s->size; i++)
    {
        if(s->data[i] > 0)
            printf("%d<-", s->data[i]);
    }
    printf("\n\n");
}

//查找
void find(struct seq_list *s,int num)
{
    int i = 0;
    for (i = 0; i < s->size; i++)
    {
        if(s->data[i] == num)
        {
            printf("find it ok %d<-\n", s->data[i]);
            return;
        }
            
    }
    printf("find it no\n");  
}

//修改
void change(struct seq_list *s,int num,int change_num)
{
    int i = 0;
    for (i = 0; i < s->size; i++)
    {
        if(s->data[i] == num)
        {
            s->data[i] = change_num;
            printf("change it ok %d<- to %d<-\n", num,change_num);
            return;
        }
            
    }
    printf("change it no\n");  
}

//释放顺序表
void release(struct seq_list *s)
{
    //先释放小的
    free(s->data);

    //再释放大的
    free(s);

    printf("release ok\n");
}

int main(int argc, char **argv)
{
    // 初始化一个顺序表(>1) 数组的大小在你初始化的时候就已经固定了
    struct seq_list *s = init_list(6);
    if (s == NULL)
    {
        printf("init seq_list fail\n");
        return -1;
    }

    /*
        增
    */
    #if 1
    // 尾插
    printf("[inset_tail:]\n");
    inset_tail(s, 40);
    inset_tail(s, 50);
    inset_tail(s, 60);
    display(s);
    #endif

    #if 1
    // 头插
    printf("[inset_head:]\n");
    inset_head(s, 30);
    inset_head(s, 20);
    inset_head(s, 10);
    display(s);
    #endif

    /*
        删
    */
     #if 1
    // 尾删
    printf("[delete_tail:]\n");
    delete_tail(s);
    display(s);
    #endif

     #if 1
    // 头删
    printf("[delete_head:]\n");
    delete_head(s);
    display(s);
    #endif

    /*
        查找(遍历的另外一种形式)
    */
    printf("[find:]\n");
    find(s,30);

    /*
        修改(遍历的另外一种形式)
    */
    printf("[change:]\n");
    change(s,30,300);  
    display(s);
    
    /*
        释放顺序表
    */
    release(s);

    return 0;
}